home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / fsdm / fsdmDisk.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-19  |  38.3 KB  |  1,372 lines

  1. /* 
  2.  * fsdmDisk.c --
  3.  *
  4.  *    Routines related to managing local disks domains.  Each partition of
  5.  *    a local    disk (partitions are defined by a table on the disk header) is
  6.  *    called a ``domain''.  Fsdm_AttachDisk attaches a domain into the file
  7.  *    system, and FsDeattachDisk removes it.  A domain is given
  8.  *    a number the first time it is ever attached.  This is recorded on
  9.  *    the disk so it doesn't change between boots.  The domain number is
  10.  *    used to identify disks, and a domain number plus a file number is
  11.  *    used to identify files.  Fsdm_DomainFetch is used to get the state
  12.  *    associated with a disk, and Fsdm_DomainRelease releases the reference
  13.  *    on the state.  Fsdm_DetachDisk checks the references on domains in
  14.  *    the normal (non-forced) case so that active disks aren't detached.
  15.  *
  16.  * Copyright 1987 Regents of the University of California
  17.  * All rights reserved.
  18.  * Permission to use, copy, modify, and distribute this
  19.  * software and its documentation for any purpose and without
  20.  * fee is hereby granted, provided that the above copyright
  21.  * notice appear in all copies.  The University of California
  22.  * makes no representations about the suitability of this
  23.  * software for any purpose.  It is provided "as is" without
  24.  * express or implied warranty.
  25.  */
  26.  
  27. #ifndef lint
  28. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/fsdm/fsdmDisk.c,v 9.13 91/01/09 13:00:03 mgbaker Exp $ SPRITE (Berkeley)";
  29. #endif not lint
  30.  
  31.  
  32. #include "sprite.h"
  33.  
  34. #include "fs.h"
  35. #include "fsutil.h"
  36. #include "fsconsist.h"
  37. #include "fsdm.h"
  38. #include "fslcl.h"
  39. #include "fsNameOps.h"
  40. #include "fsio.h"
  41. #include "fsprefix.h"
  42. #include "devDiskLabel.h"
  43. #include "dev.h"
  44. #include "devFsOpTable.h"
  45. #include "sync.h"
  46. #include "rpc.h"
  47. #include "fsioDevice.h"
  48. #include "fsdmInt.h"
  49. #include "string.h"
  50. #include "fscache.h"
  51.  
  52.  
  53. #include "ofs.h"
  54. #include "lfs.h"
  55.  
  56.  
  57. /*
  58.  * A table of domains indexed by domain number.  For use by a server
  59.  * to map from domain number to info about the domain.
  60.  */
  61. Fsdm_Domain *fsdmDomainTable[FSDM_MAX_LOCAL_DOMAINS];
  62. static int domainTableIndex = 0;
  63.  
  64. Sync_Lock    domainTableLock = Sync_LockInitStatic("Fs:domainTableLock");
  65. #define LOCKPTR (&domainTableLock)
  66.  
  67. /*
  68.  * Data structure will list of registered disk storage managers and their
  69.  * attach procedures.  This list is stored as an array and used in the
  70.  * Fsdm_AttachDisk procedure.
  71.  */
  72.  
  73. typedef struct StorageManagerList {
  74.     char    *typeName;    /* Name of storage manager type. */
  75.     ReturnStatus (*attachProc) _ARGS_((Fs_Device *devicePtr, 
  76.             char *localName, int flags, int *domainNumPtr)); 
  77.                 /* Disk attach procedure. */
  78. } StorageManagerList;
  79.  
  80. #define    MAX_STORAGE_MANAGER_TYPES 4
  81. static StorageManagerList storageManagers[MAX_STORAGE_MANAGER_TYPES];
  82.  
  83. static int numStorageManagers = 0;    /* Number of storage managers. */
  84. /*
  85.  * Forward declarations.
  86.  */
  87. static Boolean OkToDetach _ARGS_((Fsdm_Domain *domainPtr));
  88. static void MarkDomainDown _ARGS_((Fsdm_Domain *domainPtr));
  89.  
  90.  
  91.  
  92. /*
  93.  *----------------------------------------------------------------------
  94.  *
  95.  * Fsdm_RegisterDiskManager --
  96.  *
  97.  *    Register the attach procedure of a disk storage manager. 
  98.  *
  99.  * Results:
  100.  *    None.
  101.  *
  102.  * Side effects:
  103.  *    Attach procedure added to list.
  104.  *
  105.  *----------------------------------------------------------------------
  106.  */
  107. void
  108. Fsdm_RegisterDiskManager(typeName, attachProc)
  109.     char    *typeName;    /* Storage manger type name. */
  110.     ReturnStatus (*attachProc)  _ARGS_((Fs_Device *devicePtr, 
  111.             char *localName, int flags, int *domainNumPtr));
  112.             /* Disk attach procedure. */
  113. {
  114.     LOCK_MONITOR;
  115.  
  116.     if (numStorageManagers >= MAX_STORAGE_MANAGER_TYPES) {
  117.     UNLOCK_MONITOR;
  118.     panic("Fsdm_RegisterDiskManager: Can't register %s, %s (%d)\n",
  119.         typeName, "Too many disk storage managers registered", 
  120.             numStorageManagers);
  121.     return;
  122.     }
  123.     storageManagers[numStorageManagers].typeName = typeName;
  124.     storageManagers[numStorageManagers].attachProc = attachProc;
  125.     numStorageManagers++;
  126.     UNLOCK_MONITOR;
  127. }
  128.  
  129. /*
  130.  *----------------------------------------------------------------------
  131.  *
  132.  * Fsdm_AttachDiskByHandle --
  133.  *
  134.  *    Make a particular open Handle correspond to a prefix. Calls 
  135.  *    Fsdm_AttachDisk to do real work.
  136.  *
  137.  * Results:
  138.  *    The SUCCESS if disk attach otherwise a Sprite return status.
  139.  *
  140.  * Side effects:
  141.  *    Many - Those of Fsdm_AttachDisk.
  142.  *
  143.  *----------------------------------------------------------------------
  144.  */
  145.  
  146. ReturnStatus
  147. Fsdm_AttachDiskByHandle(ioHandlePtr, localName, flags)
  148.     Fs_HandleHeader *ioHandlePtr; /* Open device handle of domain. */
  149.     char *localName;        /* The local prefix for the domain */
  150.     int flags;            /* FS_ATTACH_READ_ONLY or FS_ATTACH_LOCAL */
  151. {
  152.     Fsio_DeviceIOHandle *devHandlePtr = (Fsio_DeviceIOHandle *) ioHandlePtr;
  153.     return Fsdm_AttachDisk(&devHandlePtr->device, localName, flags);
  154. }
  155.  
  156.  
  157. /*
  158.  *----------------------------------------------------------------------
  159.  *
  160.  * Fsdm_AttachDisk --
  161.  *
  162.  *    Make a particular local disk partition correspond to a prefix.
  163.  *    This makes sure the disk is up, reads the domain header,
  164.  *    and calls the initialization routine for the block I/O module
  165.  *    of the disk's driver.  By the time this is called the device
  166.  *    initialization routines have already been called from Dev_Config
  167.  *    so the device driver knows how the disk is partitioned into
  168.  *    domains.  This routine sees if the domain is formatted correctly,
  169.  *    and if so attaches it to the set of domains.
  170.  *
  171.  * Results:
  172.  *    SUCCESS if the disk was readable and had a good domain header.
  173.  *
  174.  * Side effects:
  175.  *    Sets up the Fsutil_DomainInfo for the domain.
  176.  *
  177.  *----------------------------------------------------------------------
  178.  */
  179. ReturnStatus
  180. Fsdm_AttachDisk(devicePtr, localName, flags)
  181.     register Fs_Device *devicePtr;    /* Device info from I/O handle */
  182.     char *localName;            /* The local prefix for the domain */
  183.     int flags;            /* FS_ATTACH_READ_ONLY|FS_ATTACH_LOCAL 
  184.                  * or FS_DEFAULT_DOMAIN */
  185. {
  186.     ReturnStatus status;        /* Error code */
  187.     register Fsdm_Domain *domainPtr;    /* Top level info for the domain stored
  188.                      * on the device */
  189.     Fsio_FileIOHandle    *handlePtr;    /* Reference to file handle for root */
  190.     Fs_FileID        fileID;
  191.     int        domainNum;        /* Domain number. */
  192.     int        prefixFlags;        /* For installing the prefix */
  193.     int        devFlags;        /* Device flags. */
  194.     int     useFlags;        /* Use flags. */
  195.     int        i;
  196.  
  197.     /*
  198.      * Open the raw disk device so we can grub around in the header info.
  199.      */
  200.     useFlags = (flags | FS_ATTACH_READ_ONLY) ? FS_READ : (FS_READ|FS_WRITE);
  201.     status = (*devFsOpTable[DEV_TYPE_INDEX(devicePtr->type)].open)
  202.         (devicePtr, useFlags, (Fs_NotifyToken) NIL, &devFlags);
  203.     if (status != SUCCESS) {
  204.     return(status);
  205.     }
  206.  
  207.  
  208.     /*
  209.      * Attempt to attach the disk under the same domain number each time.
  210.      * This is required if clients are to be able to re-open files.
  211.      */
  212.     domainNum = -1;
  213.     for (i = 0; i < numStorageManagers; i++) {
  214.     status = storageManagers[i].attachProc(devicePtr, localName, flags, 
  215.         &domainNum);
  216. #ifdef lint
  217.     status = Ofs_AttachDisk(devicePtr, localName, flags, &domainNum);
  218.     status = Lfs_AttachDisk(devicePtr, localName, flags, &domainNum);
  219. #endif /* lint */
  220.     if (domainNum >= 0) {
  221.         break;
  222.     }
  223.     }
  224.     if (status != SUCCESS) {
  225.     return status;
  226.     }
  227.     domainPtr = Fsdm_DomainFetch(domainNum, FALSE);
  228.     if (domainPtr == (Fsdm_Domain *)NIL) {
  229.     return(FAILURE);
  230.     }
  231.  
  232.     fileID.type = FSIO_LCL_FILE_STREAM;
  233.     fileID.serverID = rpc_SpriteID;
  234.     fileID.major = domainNum;
  235.     fileID.minor = FSDM_ROOT_FILE_NUMBER;
  236.     /*
  237.      * Now that the block I/O is set up we can read the file descriptor
  238.      * of the root directory of the domain.
  239.      */
  240.     status = Fsio_LocalFileHandleInit(&fileID, localName, 
  241.                 (Fsdm_FileDescriptor *) NIL, FALSE, &handlePtr);
  242.     if (status != SUCCESS) {
  243.     printf( "Fsdm_AttachDisk: %s - can't get root file handle (%x)\n",
  244.         localName, status);
  245.     domainPtr->flags |= FSDM_DOMAIN_DOWN;
  246.     return(status);
  247.     }
  248.     Fsutil_HandleUnlock(handlePtr);
  249.     /*
  250.      * The attach will succeed from this point, so print out info..
  251.      */
  252.     printf("%s: devType %#x devUnit %#x\n", localName,
  253.         devicePtr->type, devicePtr->unit);
  254.     /*
  255.      * Install a prefix for the domain.  We always import it so that
  256.      * we can get to the disk locally.  Then we either keep the domain
  257.      * private or export it depending on the flags argument.
  258.      */
  259.     prefixFlags = FSPREFIX_IMPORTED;
  260.     if (flags & FS_ATTACH_LOCAL) {
  261.     prefixFlags |= FSPREFIX_LOCAL;
  262.     printf("local ");
  263.     } else {
  264.     prefixFlags |= FSPREFIX_EXPORTED;
  265.     printf("exported ");
  266.     }
  267.     (void)Fsprefix_Install(localName, (Fs_HandleHeader *) handlePtr,
  268.               FS_LOCAL_DOMAIN,  prefixFlags);
  269.  
  270.     if (flags & FS_ATTACH_READ_ONLY) {
  271.     printf("read only\n");
  272.     } else {
  273.     printf("\n");
  274.     }
  275.  
  276.     /*
  277.      * Make sure a name hash table exists now that we have a disk attached.
  278.      */
  279.     Fslcl_NameHashInit();
  280.     Fsdm_DomainRelease(domainNum);
  281.     return(SUCCESS);
  282. }
  283.  
  284.  
  285.  
  286. /*
  287.  *----------------------------------------------------------------------
  288.  *
  289.  * Fsdm_DetachDisk --
  290.  *
  291.  *    Remove a local domain from the set of accessible domains.
  292.  *
  293.  * Results:
  294.  *    SUCCESS if the domain was already attached and all the outstanding
  295.  *    file handles could be recalled.
  296.  *
  297.  * Side effects:
  298.  *    Clears the prefix table entry for the domain.
  299.  *
  300.  *----------------------------------------------------------------------
  301.  */
  302. ReturnStatus
  303. Fsdm_DetachDisk(prefixName)
  304.     char    *prefixName;    /* Name that the disk is attached under. */
  305. {
  306.     Fs_HandleHeader    *hdrPtr;
  307.     char        *lookupName;
  308.     int            domainType;
  309.     Fsprefix        *prefixPtr;
  310.     Fs_FileID        rootID;
  311.     int            serverID;
  312.     int            domain;
  313.     register Fsdm_Domain    *domainPtr;
  314.     ReturnStatus    status;
  315.  
  316.     /*
  317.      * Find the domain to detach.
  318.      */
  319.     status = Fsprefix_Lookup(prefixName, 
  320.            FSPREFIX_EXACT | FSPREFIX_EXPORTED | FSPREFIX_LOCAL,
  321.            rpc_SpriteID, &hdrPtr, &rootID, &lookupName,
  322.            &serverID, &domainType, &prefixPtr);
  323.     if (status != SUCCESS) {
  324.     return(status);
  325.     } else if (hdrPtr->fileID.type != FSIO_LCL_FILE_STREAM) {
  326.     return(GEN_INVALID_ARG);
  327.     }
  328.     domain = hdrPtr->fileID.major;
  329.     domainPtr = Fsdm_DomainFetch(domain, FALSE);
  330.     if (domainPtr == (Fsdm_Domain *)NIL) {
  331.     return(FS_DOMAIN_UNAVAILABLE);
  332.     }
  333.  
  334.     /*
  335.      * Recall dirty blocks from remote clients, and copy dirty file descriptors
  336.      * into their cache blocks.  Once done, don't allow any more dirty
  337.      * blocks to enter the cache.
  338.      */
  339.     Fsconsist_GetAllDirtyBlocks(domain, TRUE);    
  340.     status = Fsutil_HandleDescWriteBack(FALSE, -1);
  341.     if (status != SUCCESS) {
  342.     printf( "Fsdm_DetachDisk: %s - handle write-back failed <%x>.\n",
  343.         domainPtr->domainPrefix, status);
  344.     }
  345.     /*
  346.      * Mark the domain and wait for other users of the domain to leave.
  347.      * The user can interrupt this wait, at which point we bail out.
  348.      */
  349.     if (!OkToDetach(domainPtr)) {
  350.     Fsdm_DomainRelease(domain);
  351.     return(FS_FILE_BUSY);
  352.     }
  353.     /*
  354.      * Nuke the prefix table entry.  Actually, this closes the handle
  355.      * and leaves the prefix entry with no handle.
  356.      */
  357.     Fsprefix_HandleClose(prefixPtr, FSPREFIX_EXPORTED);
  358.     /*
  359.      * Write all dirty blocks, bitmaps, etc. to disk and take the
  360.      * domain down.
  361.      */
  362.     status = domainPtr->domainOpsPtr->detachDisk(domainPtr);
  363.     MarkDomainDown(domainPtr);
  364.     return(status);
  365. }
  366.  
  367.  
  368. /*
  369.  *----------------------------------------------------------------------
  370.  *
  371.  * Fsdm_DomainWriteBack --
  372.  *
  373.  *    Force all domain information to disk.
  374.  *
  375.  * Results:
  376.  *    Error code if the write failed.
  377.  *
  378.  * Side effects:
  379.  *    None.
  380.  *
  381.  *----------------------------------------------------------------------
  382.  */
  383. void
  384. Fsdm_DomainWriteBack(domain, shutdown, detach)
  385.     int        domain;        /* Domain number, -1 means all domains */
  386.     Boolean    shutdown;    /* TRUE if are syncing to shutdown the system.*/
  387.     Boolean    detach;        /* TRUE if are writing back as part of 
  388.                  * detaching the domain.  This is used to force 
  389.                  * the domain fetch to work even if it is
  390.                  * marked as down. */
  391. {
  392.     register    Fsdm_Domain    *domainPtr;
  393.     int                firstDomain;
  394.     register int         lastDomain;
  395.     register int         i;
  396.  
  397.     if (domain >= 0) {
  398.     /*
  399.      * Write back a particular domain.
  400.      */
  401.     firstDomain = domain;
  402.     lastDomain = domain;
  403.     } else {
  404.     /*
  405.      * Write back all domains.
  406.      */
  407.     firstDomain = 0;
  408.     lastDomain = FSDM_MAX_LOCAL_DOMAINS - 1;
  409.     detach = FALSE;
  410.     }
  411.     for (i = firstDomain; i <= lastDomain; i++) {
  412.     domainPtr = Fsdm_DomainFetch(i, detach);
  413.     if (domainPtr != (Fsdm_Domain *) NIL) {
  414.         (void ) domainPtr->domainOpsPtr->writeBack(domainPtr, shutdown);
  415. #ifdef lint
  416.         (void) Ofs_DomainWriteBack(domainPtr, shutdown);
  417.         (void) Lfs_DomainWriteBack(domainPtr, shutdown);
  418. #endif /* lint */
  419.         Fsdm_DomainRelease(i);
  420.     }
  421.     }
  422. }
  423.  
  424.  
  425.  
  426. /*
  427.  *----------------------------------------------------------------------
  428.  *
  429.  * Fsdm_InstallDomain --
  430.  *
  431.  *    Install a Fsdm_Domain structure for a newly attached local domain and
  432.  *    save it in the domain table.  The index into this table is
  433.  *    returned and passed around as the identifier for the domain.
  434.  *
  435.  * Results:
  436.  *    The domain number.
  437.  *
  438.  * Side effects:
  439.  *    Save the info in fsVolumeTable
  440.  *
  441.  *----------------------------------------------------------------------
  442.  */
  443. ENTRY ReturnStatus
  444. Fsdm_InstallDomain(domainNumber, serverID, prefixName, flags, domainPtrPtr)
  445.     int        domainNumber;    /* Domain nubmer to use. */
  446.     int        serverID;    /* Server ID from disk. */
  447.     char    *prefixName;    /* Prefix of domain. */
  448.     int        flags;        /* Domain flags. */
  449.     Fsdm_Domain **domainPtrPtr;    /* OUT: Return domain pointer. */
  450. {
  451.     Fsdm_Domain *oldDomainPtr, *domainPtr;
  452.  
  453.     LOCK_MONITOR;
  454.  
  455.     if (domainNumber == -1) {
  456.     while ((domainTableIndex < FSDM_MAX_LOCAL_DOMAINS) && 
  457.         (fsdmDomainTable[domainTableIndex] != (Fsdm_Domain *)NIL)) {
  458.         domainTableIndex++;
  459.     }
  460.     if (domainTableIndex == FSDM_MAX_LOCAL_DOMAINS) {
  461.         printf("Fsdm_InstallDomain: too many local domains.\n");
  462.         domainNumber = -1;
  463.         UNLOCK_MONITOR;
  464.         return(FS_DOMAIN_UNAVAILABLE);
  465.     }
  466.     domainNumber = domainTableIndex;
  467.     domainTableIndex++;
  468.     } 
  469.     if ((domainNumber < 0) || (domainNumber >= FSDM_MAX_LOCAL_DOMAINS)) {
  470.     printf("Fsdm_InstallDomain: domain number (%d) for %s out of range.\n",
  471.         domainNumber, prefixName);
  472.     UNLOCK_MONITOR;
  473.     return(FS_DOMAIN_UNAVAILABLE);
  474.     } 
  475.  
  476.     oldDomainPtr = fsdmDomainTable[domainNumber];
  477.     if (oldDomainPtr != (Fsdm_Domain *)NIL) {
  478.     if (!(oldDomainPtr->flags & FSDM_DOMAIN_DOWN)) {
  479.         printf("Fsdm_AttachDisk: %s already attached at domain %d\n",
  480.             oldDomainPtr->domainPrefix, domainNumber);
  481.         *domainPtrPtr = oldDomainPtr;
  482.         UNLOCK_MONITOR;
  483.         return(FS_FILE_BUSY);
  484.     } 
  485.     domainPtr = oldDomainPtr;
  486.     } else {
  487.     domainPtr = (Fsdm_Domain *) malloc(sizeof(Fsdm_Domain));
  488.     bzero((char *) domainPtr, sizeof(Fsdm_Domain));
  489.     fsdmDomainTable[domainNumber] = domainPtr;
  490.     }
  491.     domainPtr->domainPrefix = malloc(strlen(prefixName)+1);
  492.     (void)strcpy(domainPtr->domainPrefix, prefixName);
  493.  
  494.     domainPtr->domainNumber = domainNumber;
  495.     domainPtr->flags = 0;
  496.  
  497.     *domainPtrPtr = domainPtr;
  498.  
  499.      if (rpc_SpriteID == 0) {
  500.     /*
  501.      * Use the spriteID on the 1st disk if we don't know it by now.
  502.      * This is the last resort.  Usually reverse arp or the hook
  503.      * in the RPC protocol have established our ID.  If there are
  504.      * no other Sprite hosts running on the network , however,
  505.      * then this code will execute.
  506.      */
  507.     printf(
  508.       "Fsdm_InstallDomain: setting rpc_SpriteID to 0x%x from disk header\n",
  509.             serverID);
  510.     if (serverID <= 0) {
  511.         panic("Bad sprite ID\n");
  512.     }
  513.     rpc_SpriteID = serverID;
  514.     }
  515.  
  516.     if (flags & FS_DEFAULT_DOMAIN) {
  517.     domainPtr->flags = FSDM_DOMAIN_ATTACH_BOOT;
  518.     } else {
  519.     domainPtr->flags = 0;
  520.     }
  521.     UNLOCK_MONITOR;
  522.  
  523.     return SUCCESS;
  524. }
  525.  
  526.  
  527. /*
  528.  *----------------------------------------------------------------------
  529.  *
  530.  * OkToDetach --
  531.  *
  532.  *    Wait for activity in a domain to end and then mark the
  533.  *    domain as being down.  This prints a warning message and
  534.  *    waits in an interruptable state if the domain is in use.
  535.  *    Our caller should back out if we return FALSE.
  536.  *
  537.  * Results:
  538.  *    TRUE if it is ok to detach the domain.
  539.  *
  540.  * Side effects:
  541.  *    The FSDM_DOMAIN_GOING_DOWN flag is set in the domain.
  542.  *
  543.  *----------------------------------------------------------------------
  544.  */
  545. static ENTRY Boolean
  546. OkToDetach(domainPtr)
  547.     Fsdm_Domain    *domainPtr;
  548. {
  549.     LOCK_MONITOR;
  550.  
  551.     domainPtr->flags |= FSDM_DOMAIN_GOING_DOWN;
  552.     /*
  553.      * Wait until we are the only user of the domain because 
  554.      * noone else but the cache block cleaner or us should be using this
  555.      * domain once we set this flag.
  556.      */
  557.     while (domainPtr->refCount > 1) {
  558.     printf("Waiting for busy domain \"%s\"\n",
  559.         domainPtr->domainPrefix);
  560.     if (Sync_Wait(&domainPtr->condition, TRUE)) {
  561.         domainPtr->flags &= ~FSDM_DOMAIN_GOING_DOWN;
  562.         UNLOCK_MONITOR;
  563.         return(FALSE);    /* Interrupted while waiting, domain busy */
  564.     }
  565.     }
  566.  
  567.     UNLOCK_MONITOR;
  568.     return(TRUE);
  569. }
  570.  
  571. /*
  572.  *----------------------------------------------------------------------
  573.  *
  574.  * MarkDomainDown --
  575.  *
  576.  *    Mark the domain as being down.
  577.  *
  578.  * Results:
  579.  *    None.
  580.  *
  581.  * Side effects:
  582.  *    The FSDM_DOMAIN_DOWN flag is set.
  583.  *
  584.  *----------------------------------------------------------------------
  585.  */
  586. static ENTRY void
  587. MarkDomainDown(domainPtr)
  588.     Fsdm_Domain    *domainPtr;
  589. {
  590.     LOCK_MONITOR;
  591.  
  592.     domainPtr->flags |= FSDM_DOMAIN_DOWN;
  593.     if (domainPtr->refCount > 1) {
  594.     printf("DomainDown: Refcount > 1\n");
  595.     }
  596.     domainPtr->refCount = 0;
  597.  
  598.     UNLOCK_MONITOR;
  599. }
  600.  
  601.  
  602. /*
  603.  *----------------------------------------------------------------------
  604.  *
  605.  * Fsdm_DomainFetch --
  606.  *
  607.  *    Return a pointer to the given domain if it is available.
  608.  *
  609.  * Results:
  610.  *    Pointer to the domain.
  611.  *
  612.  * Side effects:
  613.  *    Reference count in the domain incremented.
  614.  *
  615.  *----------------------------------------------------------------------
  616.  */
  617. ENTRY Fsdm_Domain *
  618. Fsdm_DomainFetch(domain, dontStop)
  619.     int        domain;        /* Domain to fetch. */
  620.     Boolean    dontStop;    /* Fetch this domain unless it has been
  621.                  * totally detached. */
  622. {
  623.     register    Fsdm_Domain    *domainPtr;
  624.  
  625.     LOCK_MONITOR;
  626.  
  627.     if (domain < 0 || domain >= FSDM_MAX_LOCAL_DOMAINS) {
  628.     printf( "Fsdm_DomainFetch, bad domain number <%d>\n",
  629.         domain);
  630.     domainPtr = (Fsdm_Domain *)NIL;
  631.     } else {
  632.     domainPtr = fsdmDomainTable[domain];
  633.     }
  634.     if (domainPtr != (Fsdm_Domain *) NIL) {
  635.     if (domainPtr->flags & FSDM_DOMAIN_DOWN) {
  636.         domainPtr = (Fsdm_Domain *) NIL;
  637.     } else if (dontStop || !(domainPtr->flags & FSDM_DOMAIN_GOING_DOWN)) {
  638.         domainPtr->refCount++;
  639.     } else {
  640.         domainPtr = (Fsdm_Domain *) NIL;
  641.     }
  642.     }
  643.  
  644.     UNLOCK_MONITOR;
  645.     return(domainPtr);
  646. }
  647.  
  648.  
  649. /*
  650.  *----------------------------------------------------------------------
  651.  *
  652.  * Fsdm_DomainRelease --
  653.  *
  654.  *    Release access to the given domain using a domain number.
  655.  *
  656.  * Results:
  657.  *    None.
  658.  *
  659.  * Side effects:
  660.  *    Reference count for the domain decremented.
  661.  *
  662.  *----------------------------------------------------------------------
  663.  */
  664. ENTRY void
  665. Fsdm_DomainRelease(domainNum)
  666.     int    domainNum;
  667. {
  668.     register    Fsdm_Domain    *domainPtr;
  669.  
  670.     LOCK_MONITOR;
  671.  
  672.     domainPtr = fsdmDomainTable[domainNum];
  673.     if (domainPtr == (Fsdm_Domain *)NIL) {
  674.     panic( "Fsdm_DomainRelease: NIL domain pointer\n");
  675.     }
  676.  
  677.     domainPtr->refCount--;
  678.     if (domainPtr->refCount < 0) {
  679.     panic( "Fsdm_DomainRelease: Negative ref count on domain %d\n", 
  680.             domainNum);
  681.     }
  682.     if (domainPtr->refCount == 0) {
  683.     Sync_Broadcast(&domainPtr->condition);
  684.     }
  685.  
  686.     UNLOCK_MONITOR;
  687. }
  688.  
  689.  
  690. /*
  691.  *----------------------------------------------------------------------
  692.  *
  693.  * Fsdm_IsSunLabel --
  694.  *
  695.  *    Poke around in the input buffer and see if it looks like
  696.  *    a Sun format disk label.
  697.  *
  698.  * Results:
  699.  *    TRUE or FALSE
  700.  *
  701.  * Side effects:
  702.  *    None.
  703.  *
  704.  *----------------------------------------------------------------------
  705.  */
  706. Boolean
  707. Fsdm_IsSunLabel(buffer)
  708.     Address buffer;    /* Buffer containing zero'th sector */
  709. {
  710.     register Sun_DiskLabel *sunLabelPtr;
  711.  
  712.     sunLabelPtr = (Sun_DiskLabel *)buffer;
  713.     if (sunLabelPtr->magic == SUN_DISK_MAGIC) {
  714.     /*
  715.      * Should check checkSum...
  716.      */
  717.     return(TRUE);
  718.     } else {
  719.     return(FALSE);
  720.     }
  721. }
  722.  
  723. /*
  724.  *----------------------------------------------------------------------
  725.  *
  726.  * Fsdm_IsSpriteLabel --
  727.  *
  728.  *    Poke around in the input buffer and see if it looks like
  729.  *    a Sprite format disk header.
  730.  *
  731.  * Results:
  732.  *    TRUE or FALSE
  733.  *
  734.  * Side effects:
  735.  *    None.
  736.  *
  737.  *----------------------------------------------------------------------
  738.  */
  739. Boolean
  740. Fsdm_IsSpriteLabel(buffer)
  741.     Address buffer;    /* Buffer containing zero'th sector */
  742. {
  743.     register Fsdm_DiskHeader    *diskHeaderPtr;
  744.     register int         index;
  745.     register int         checkSum;
  746.     int                *headerPtr;
  747.  
  748.     diskHeaderPtr = (Fsdm_DiskHeader *)buffer;
  749.     if (diskHeaderPtr->magic == FSDM_DISK_MAGIC) {
  750.     /*
  751.      * Check the checkSum which set so that an XOR of all the
  752.      * ints in the disk header comes out to FSDM_DISK_MAGIC also.
  753.      */
  754.     checkSum = 0;
  755.     for (index = 0, headerPtr = (int *)buffer;
  756.          index < DEV_BYTES_PER_SECTOR;
  757.          index += sizeof(int), headerPtr++) {
  758.         checkSum ^= *headerPtr;
  759.     }
  760.     if (checkSum == FSDM_DISK_MAGIC) {
  761.         return(TRUE);
  762.     } else {
  763.         printf("IsSpriteLabel: checksum mismatch <%x>\n", checkSum);
  764.     }
  765.     }
  766.     return(FALSE);
  767. }
  768.  
  769. /*
  770.  *----------------------------------------------------------------------
  771.  *
  772.  * Fsdm_IsDecLabel --
  773.  *
  774.  *    Poke around in the input buffer and see if it looks like
  775.  *    a Dec format disk label.
  776.  *
  777.  * Results:
  778.  *    TRUE or FALSE
  779.  *
  780.  * Side effects:
  781.  *    None.
  782.  *
  783.  *----------------------------------------------------------------------
  784.  */
  785. Boolean
  786. Fsdm_IsDecLabel(buffer)
  787.     Address buffer;    /* Buffer containing zero'th sector */
  788. {
  789.     register Dec_DiskLabel *decLabelPtr;
  790.  
  791.     decLabelPtr = (Dec_DiskLabel *)buffer;
  792.     if (decLabelPtr->magic == DEC_LABEL_MAGIC) {
  793.     if (decLabelPtr->spriteMagic == FSDM_DISK_MAGIC &&
  794.         decLabelPtr->version == DEC_LABEL_VERSION) {
  795.         return TRUE;
  796.     } else {
  797.         printf("Dec label version mismatch: %x vs %x\n",
  798.             decLabelPtr->version, DEC_LABEL_VERSION);
  799.     }
  800.     }
  801.     return(FALSE);
  802. }
  803.  
  804.  
  805. /*
  806.  *----------------------------------------------------------------------
  807.  *
  808.  * Fsdm_Init --
  809.  *
  810.  *    Initialized the disk management routines. This means initializing
  811.  *    the domain table to NIL.
  812.  *
  813.  * Results:
  814.  *    None.
  815.  *
  816.  * Side effects:
  817.  *    None.
  818.  *
  819.  *----------------------------------------------------------------------
  820.  */
  821.  
  822. void
  823. Fsdm_Init()
  824. {
  825.     register int index;
  826.     for (index = 0; index < FSDM_MAX_LOCAL_DOMAINS; index++) {
  827.         fsdmDomainTable[index] = (Fsdm_Domain *) NIL;
  828.     }
  829.     Ofs_Init();
  830.     Lfs_Init();
  831. }
  832.  
  833.  
  834.  
  835. /*
  836.  *----------------------------------------------------------------------
  837.  *
  838.  * Fsdm_RereadSummaryInfo --
  839.  *
  840.  *    Reread the summary sector associated with the prefix and update
  841.  *    the domain information. This should be called if the summary
  842.  *    sector on the disk has been changed since the domain was attached.
  843.  *
  844.  * Results:
  845.  *    SUCCESS if the summary sector was read correctly and the 
  846.  *    information was updated
  847.  *
  848.  * Side effects:
  849.  *    The summary sector information associated with the domain is
  850.  *    updated.
  851.  *
  852.  *----------------------------------------------------------------------
  853.  */
  854.  
  855. ReturnStatus
  856. Fsdm_RereadSummaryInfo(prefixName)
  857.    char    *prefixName;    /* Name that the disk is attached under. */
  858. {
  859.     Fs_HandleHeader    *hdrPtr;
  860.     char        *lookupName;
  861.     int            domainType;
  862.     Fsprefix        *prefixPtr;
  863.     Fs_FileID        rootID;
  864.     int            serverID;
  865.     int            domain;
  866.     register Fsdm_Domain    *domainPtr;
  867.     ReturnStatus    status;
  868.  
  869.     /*
  870.      * Find the correct domain.
  871.      */
  872.     status = Fsprefix_Lookup(prefixName, 
  873.            FSPREFIX_EXACT | FSPREFIX_EXPORTED | FSPREFIX_LOCAL,
  874.            rpc_SpriteID, &hdrPtr, &rootID, &lookupName, &serverID,
  875.            &domainType, &prefixPtr);
  876.     if (status != SUCCESS) {
  877.     return(status);
  878.     } else if (hdrPtr->fileID.type != FSIO_LCL_FILE_STREAM) {
  879.     return(GEN_INVALID_ARG);
  880.     }
  881.     domain = hdrPtr->fileID.major;
  882.     domainPtr = Fsdm_DomainFetch(domain, FALSE);
  883.     if (domainPtr == (Fsdm_Domain *)NIL) {
  884.     return(FS_DOMAIN_UNAVAILABLE);
  885.     }
  886.     /*
  887.      * Read the summary sector.
  888.      */
  889.     status = domainPtr->domainOpsPtr->rereadSummary(domainPtr);
  890. #ifdef lint
  891.     status = Lfs_RereadSummaryInfo(domainPtr);
  892.     status = Ofs_RereadSummaryInfo(domainPtr);
  893. #endif /* lint */
  894.     return status;
  895. }
  896.  
  897. /*
  898.  *----------------------------------------------------------------------
  899.  *
  900.  * Fsdm_FileBlockRead --
  901.  *
  902.  *    Read in a cache block.  
  903.  *
  904.  * Results:
  905.  *    The results of the disk read.
  906.  *
  907.  * Side effects:
  908.  *    The buffer is filled with the number of bytes indicated by
  909.  *    the bufSize parameter.  The blockPtr->blockSize is modified to
  910.  *    reflect how much data was actually read in.  The unused part
  911.  *    of the block is filled with zeroes so that higher levels can
  912.  *    always assume the block has good stuff in all parts of it.
  913.  *
  914.  *----------------------------------------------------------------------
  915.  */
  916. /*ARGSUSED*/
  917. ReturnStatus
  918. Fsdm_FileBlockRead(hdrPtr, blockPtr, remoteWaitPtr)
  919.     Fs_HandleHeader    *hdrPtr;    /* Handle on a local file. */
  920.     Fscache_Block    *blockPtr;    /* Cache block to read in.  This assumes
  921.                      * the blockNum, blockAddr (buffer area)
  922.                      * and blockSize are set.  This modifies
  923.                      * blockSize if less bytes were read
  924.                      * because of EOF. */
  925.     Sync_RemoteWaiter *remoteWaitPtr;    /* NOTUSED */
  926. {
  927.     register Fsio_FileIOHandle *handlePtr = (Fsio_FileIOHandle *)hdrPtr;
  928.     register    Fsdm_Domain     *domainPtr;
  929.     ReturnStatus         status;
  930.  
  931.     domainPtr = Fsdm_DomainFetch(handlePtr->hdr.fileID.major, FALSE);
  932.     if (domainPtr == (Fsdm_Domain *) NIL) {
  933.     return(FS_DOMAIN_UNAVAILABLE);
  934.     }
  935.  
  936.     status = domainPtr->domainOpsPtr->fileBlockRead(domainPtr, handlePtr,
  937.                 blockPtr);
  938. #ifdef lint
  939.     status = Lfs_FileBlockRead(domainPtr,handlePtr,blockPtr);
  940.     status = Ofs_FileBlockRead(domainPtr,handlePtr,blockPtr);
  941. #endif /* lint */
  942.     Fsdm_DomainRelease(handlePtr->hdr.fileID.major);
  943.     return(status);
  944. }
  945.  
  946. /*
  947.  *----------------------------------------------------------------------
  948.  *
  949.  * Fsdm_FileBlockWrite --
  950.  *
  951.  *    Write out a cache block.  
  952.  *
  953.  * Results:
  954.  *    The return code from the driver, or FS_DOMAIN_UNAVAILABLE if
  955.  *    the domain has been un-attached.
  956.  *
  957.  * Side effects:
  958.  *    The device write.
  959.  *
  960.  *----------------------------------------------------------------------
  961.  */
  962. /*ARGSUSED*/
  963. ReturnStatus
  964. Fsdm_FileBlockWrite(hdrPtr, blockPtr, flags)
  965.     Fs_HandleHeader *hdrPtr;    /* I/O handle for the file. */
  966.     Fscache_Block *blockPtr;    /* Cache block to write out. */
  967.     int        flags;        /* IGNORED */
  968. {
  969.     register Fsio_FileIOHandle *handlePtr = (Fsio_FileIOHandle *)hdrPtr;
  970.     register    Fsdm_Domain     *domainPtr;
  971.     ReturnStatus        status;
  972.  
  973.     domainPtr = Fsdm_DomainFetch(handlePtr->hdr.fileID.major, TRUE);
  974.     if (domainPtr == (Fsdm_Domain *)NIL) {
  975.     return(FS_DOMAIN_UNAVAILABLE);
  976.     }
  977.     status = domainPtr->domainOpsPtr->fileBlockWrite(domainPtr, handlePtr, 
  978.         blockPtr);
  979.  
  980. #ifdef lint
  981.     status = Lfs_FileBlockWrite(domainPtr,handlePtr,blockPtr);
  982.     status = Ofs_FileBlockWrite(domainPtr,handlePtr,blockPtr);
  983. #endif /* lint */
  984.     Fsdm_DomainRelease(handlePtr->hdr.fileID.major);
  985.     return(status);
  986. }
  987.  
  988.  
  989. /*
  990.  *----------------------------------------------------------------------
  991.  *
  992.  * Fsdm_FileTrunc --
  993.  *
  994.  *    Truncate a file.  
  995.  *
  996.  * Results:
  997.  *    The return code from the driver, or FS_DOMAIN_UNAVAILABLE if
  998.  *    the domain has been un-attached.
  999.  *
  1000.  * Side effects:
  1001.  *    The device write.
  1002.  *
  1003.  *----------------------------------------------------------------------
  1004.  */
  1005. /*ARGSUSED*/
  1006. ReturnStatus
  1007. Fsdm_FileTrunc(hdrPtr, size, delete)
  1008.     Fs_HandleHeader *hdrPtr;    /* I/O handle for the file. */
  1009.     int            size;    /* Size to truncate to. */
  1010.     Boolean        delete;    /* True if the file is being deleted. */
  1011. {
  1012.     Fsio_FileIOHandle *handlePtr = (Fsio_FileIOHandle *) hdrPtr;
  1013.     register    Fsdm_Domain     *domainPtr;
  1014.     ReturnStatus        status;
  1015.  
  1016.     domainPtr = Fsdm_DomainFetch(handlePtr->hdr.fileID.major, TRUE);
  1017.     if (domainPtr == (Fsdm_Domain *)NIL) {
  1018.     return(FS_DOMAIN_UNAVAILABLE);
  1019.     }
  1020.     status = domainPtr->domainOpsPtr->fileTrunc(domainPtr, handlePtr, size, 
  1021.                 delete);
  1022.  
  1023. #ifdef lint
  1024.     status = Lfs_FileTrunc(domainPtr, handlePtr, size, delete);
  1025.     status = Ofs_FileTrunc(domainPtr, handlePtr, size, delete);
  1026. #endif /* lint */
  1027.     Fsdm_DomainRelease(handlePtr->hdr.fileID.major);
  1028.     return(status);
  1029. }
  1030.  
  1031. /*
  1032.  *----------------------------------------------------------------------
  1033.  *
  1034.  * Fsdm_DomainInfo --
  1035.  *
  1036.  *    Return info about the given domain.
  1037.  *
  1038.  * Results:
  1039.  *    Error  if can't get to the domain.
  1040.  *
  1041.  * Side effects:
  1042.  *    The domain info struct is filled in.
  1043.  *
  1044.  *----------------------------------------------------------------------
  1045.  */
  1046. ReturnStatus
  1047. Fsdm_DomainInfo(fileIDPtr, domainInfoPtr)
  1048.     Fs_FileID        *fileIDPtr;
  1049.     Fs_DomainInfo    *domainInfoPtr;
  1050. {
  1051.     int        domain = fileIDPtr->major;
  1052.     ReturnStatus status;
  1053.     Fsdm_Domain    *domainPtr;
  1054.  
  1055.     if (domain >= FSDM_MAX_LOCAL_DOMAINS) {
  1056.     return(FS_DOMAIN_UNAVAILABLE);
  1057.     }
  1058.  
  1059.     domainPtr = Fsdm_DomainFetch(domain, FALSE);
  1060.     if (domainPtr == (Fsdm_Domain *) NIL) {
  1061.     return(FS_DOMAIN_UNAVAILABLE);
  1062.     }
  1063.     status = domainPtr->domainOpsPtr->domainInfo(domainPtr, domainInfoPtr);
  1064. #ifdef lint
  1065.     status = Lfs_DomainInfo(domainPtr, domainInfoPtr);
  1066.     status = Ofs_DomainInfo(domainPtr, domainInfoPtr);
  1067. #endif /* lint */
  1068.  
  1069.     Fsdm_DomainRelease(domain);
  1070.     return status;
  1071. }
  1072.  
  1073. /*
  1074.  *----------------------------------------------------------------------
  1075.  *
  1076.  * Fsdm_BlockAllocate --
  1077.  *
  1078.  *    Allocate disk space for the given file.  This routine only allocates
  1079.  *    one block beginning at offset and going for numBytes.   If 
  1080.  *    offset + numBytes crosses a block boundary then a panic will occur.
  1081.  *
  1082.  * Results:
  1083.  *    None.
  1084.  *
  1085.  * Side effects:
  1086.  *    The file descriptor is modified to contain pointers to the allocated
  1087.  *    blocks.  Also *blockAddrPtr is set to the block that was allocated.
  1088.  *
  1089.  *----------------------------------------------------------------------
  1090.  */
  1091. ReturnStatus
  1092. Fsdm_BlockAllocate(hdrPtr, offset, numBytes, flags, blockAddrPtr, newBlockPtr)
  1093.     register Fs_HandleHeader *hdrPtr;    /* Local file handle. */
  1094.     int         offset;        /* Offset to allocate at. */
  1095.     int         numBytes;    /* Number of bytes to allocate. */
  1096.     int            flags;        /* FSCACHE_DONT_BLOCK */
  1097.     int            *blockAddrPtr;     /* Disk address of block allocated. */
  1098.     Boolean        *newBlockPtr;    /* TRUE if there was no block allocated
  1099.                      * before. */
  1100. {
  1101.     Fsdm_Domain        *domainPtr;    /* Domain of file. */
  1102.     register Fsio_FileIOHandle *handlePtr;    /* Local file handle. */
  1103.     ReturnStatus status;
  1104.  
  1105.     handlePtr = (Fsio_FileIOHandle *) hdrPtr;
  1106.     if (offset / FS_BLOCK_SIZE != (offset + numBytes - 1) / FS_BLOCK_SIZE) {
  1107.     panic("Fsdm_BlockAllocate - ALlocation spans block boundries\n");
  1108.     return FAILURE;
  1109.     }
  1110.     domainPtr = Fsdm_DomainFetch(handlePtr->hdr.fileID.major, TRUE);
  1111.     if (domainPtr == (Fsdm_Domain *)NIL) {
  1112.     return(FS_DOMAIN_UNAVAILABLE);
  1113.     }
  1114.     status = domainPtr->domainOpsPtr->blockAlloc(domainPtr, handlePtr,
  1115.         offset, numBytes, flags, blockAddrPtr, newBlockPtr);
  1116. #ifdef lint
  1117.     status = Lfs_BlockAllocate(domainPtr, handlePtr, offset,  numBytes, flags,
  1118.                 blockAddrPtr, newBlockPtr);
  1119.     status = Ofs_BlockAllocate(domainPtr, handlePtr, offset,  numBytes, flags,
  1120.                 blockAddrPtr, newBlockPtr);
  1121. #endif /* lint */
  1122.  
  1123.     Fsdm_DomainRelease(handlePtr->hdr.fileID.major);
  1124.     return(status);
  1125. }
  1126.  
  1127. /*
  1128.  *----------------------------------------------------------------------
  1129.  *
  1130.  * Fsdm_FindFileType --
  1131.  *
  1132.  *    Map from flags in the handle to a constant corresponding to
  1133.  *    the file type for the kernel.  
  1134.  *
  1135.  * Results:
  1136.  *    The value corresponding to the file's type is returned.
  1137.  *
  1138.  * Side effects:
  1139.  *    None.
  1140.  *
  1141.  *----------------------------------------------------------------------
  1142.  */
  1143.  
  1144. int
  1145. Fsdm_FindFileType(cacheInfoPtr)
  1146.     Fscache_FileInfo *cacheInfoPtr;    /* File to determine type of */
  1147. {
  1148.     switch (cacheInfoPtr->attr.userType) {
  1149.     case FS_USER_TYPE_TMP:
  1150.         return(FSUTIL_FILE_TYPE_TMP);
  1151.     case FS_USER_TYPE_SWAP:
  1152.         return(FSUTIL_FILE_TYPE_SWAP);
  1153.     case FS_USER_TYPE_OBJECT:
  1154.         return(FSUTIL_FILE_TYPE_DERIVED);
  1155.     case FS_USER_TYPE_BINARY:
  1156.         return(FSUTIL_FILE_TYPE_BINARY);
  1157.     default:
  1158.             return(FSUTIL_FILE_TYPE_OTHER);
  1159.     }
  1160. }
  1161.  
  1162.  
  1163. /*
  1164.  *----------------------------------------------------------------------
  1165.  *
  1166.  * Fsdm_FileDescWriteBack --
  1167.  *
  1168.  *    Force the file descriptor for the handle to disk.
  1169.  *
  1170.  * Results:
  1171.  *    None.
  1172.  *
  1173.  * Side effects:
  1174.  *    File descriptor block forced to disk.
  1175.  *
  1176.  *----------------------------------------------------------------------
  1177.  */
  1178. ReturnStatus
  1179. Fsdm_FileDescWriteBack(handlePtr, doWriteBack)
  1180.      Fsio_FileIOHandle *handlePtr;    /* Handle that points
  1181.                      * to descriptor to write back. */
  1182.     Boolean        doWriteBack;    /* Do a cache write back, not only
  1183.                      * a store into the cache block. */
  1184. {
  1185. #ifdef NOTDEF
  1186.     Fs_HandleHeader    *hdrPtr = (Fs_HandleHeader *) handlePtr;
  1187. #endif NOTDEF
  1188.     register Fsdm_FileDescriptor    *descPtr;
  1189.     register Fsdm_Domain        *domainPtr;
  1190.     register ReturnStatus         status = SUCCESS;
  1191.  
  1192.     domainPtr = Fsdm_DomainFetch(handlePtr->hdr.fileID.major, FALSE);
  1193.     if (domainPtr == (Fsdm_Domain *)NIL) {
  1194.     return(FS_DOMAIN_UNAVAILABLE);
  1195.     }
  1196.     descPtr = handlePtr->descPtr;
  1197.     if (descPtr == (Fsdm_FileDescriptor *)NIL) {
  1198.     if ((handlePtr->cacheInfo.flags & FSCACHE_FILE_GONE) == 0) {
  1199.         panic("Fsdm_FileDescWriteBack: no descriptor for \"%s\" (continuable)\n",
  1200.         Fsutil_HandleName(handlePtr));
  1201.     }
  1202.     status = FS_FILE_REMOVED;
  1203.     goto exit;
  1204.     }
  1205.     /*
  1206.      * If the handle times differ from the descriptor times then force
  1207.      * them out to the descriptor.
  1208.      */
  1209.     if (descPtr->accessTime < handlePtr->cacheInfo.attr.accessTime) {
  1210.     descPtr->accessTime = handlePtr->cacheInfo.attr.accessTime;
  1211. #ifdef NOTDEF
  1212.      printf("Fsdm_FileDescWriteBack, access time changed <%d,%d> \"%s\"\n",
  1213.         hdrPtr->fileID.major, hdrPtr->fileID.minor,
  1214.         Fsutil_HandleName(hdrPtr));
  1215. #endif
  1216.     descPtr->flags |= FSDM_FD_DIRTY;
  1217.     }
  1218.     if (descPtr->dataModifyTime < handlePtr->cacheInfo.attr.modifyTime) {
  1219.     descPtr->dataModifyTime = handlePtr->cacheInfo.attr.modifyTime;
  1220. #ifdef NOTDEF
  1221.      printf("Fsdm_FileDescWriteBack, mod time changed <%d,%d> \"%s\"\n",
  1222.         hdrPtr->fileID.major, hdrPtr->fileID.minor,
  1223.         Fsutil_HandleName(hdrPtr));
  1224. #endif
  1225.     descPtr->flags |= FSDM_FD_DIRTY;
  1226.     }
  1227.     if (descPtr->dataModifyTime > descPtr->descModifyTime) {
  1228.     descPtr->descModifyTime = descPtr->dataModifyTime;
  1229. #ifdef NOTDEF
  1230.      printf("Fsdm_FileDescWriteBack, desc time changed <%d,%d> \"%s\"\n",
  1231.         hdrPtr->fileID.major, hdrPtr->fileID.minor,
  1232.         Fsutil_HandleName(hdrPtr));
  1233. #endif
  1234.     descPtr->flags |= FSDM_FD_DIRTY;
  1235.     }
  1236.     if (descPtr->flags & FSDM_FD_DIRTY) {
  1237.     status =  Fsdm_FileDescStore(handlePtr, doWriteBack);
  1238.     if (status != SUCCESS) {
  1239.         printf("Fsdm_FileDescWriteBack: Could not put desc <%d,%d> into cache\n",
  1240.             handlePtr->hdr.fileID.major,
  1241.             handlePtr->hdr.fileID.minor);
  1242.     }
  1243.     }
  1244. exit:
  1245.     Fsdm_DomainRelease(handlePtr->hdr.fileID.major);
  1246.     return(status);
  1247. }
  1248.  
  1249. /*
  1250.  *----------------------------------------------------------------------
  1251.  *
  1252.  * Fsdm_DirOpStart --
  1253.  *
  1254.  *    Mark the start of a directory operation.
  1255.  *
  1256.  * Results:
  1257.  *    
  1258.  *
  1259.  * Side effects:
  1260.  *    None.
  1261.  *
  1262.  *----------------------------------------------------------------------
  1263.  */
  1264.  
  1265. ClientData
  1266. Fsdm_DirOpStart(opFlags, dirHandlePtr, dirOffset, name, nameLen, fileNumber,
  1267.         type, fileDescPtr)
  1268.     int        opFlags;    /* Operation code and flags. See fsdm.h for
  1269.                  * definitions. */
  1270.     Fsio_FileIOHandle *dirHandlePtr;    /* Handle of directory being operated
  1271.                      * on. */
  1272.     int        dirOffset;    /* Byte offset into directory of the directory
  1273.                  * entry containing operation. -1 if offset
  1274.                  * is not known. */
  1275.     char    *name;        /* Name of object being operated on. */
  1276.     int        nameLen;    /* Length in characters of name. */
  1277.     int        fileNumber;    /* File number of objecting being operated on.*/
  1278.     int        type;        /* Type of the object being operated on. */
  1279.     Fsdm_FileDescriptor *fileDescPtr; /* FileDescriptor object being operated on
  1280.                        * before operation starts. */
  1281. {
  1282.     ClientData            clientData;
  1283.     register Fsdm_Domain    *domainPtr;
  1284.     domainPtr = Fsdm_DomainFetch(dirHandlePtr->hdr.fileID.major, FALSE);
  1285.     if (domainPtr == (Fsdm_Domain *)NIL) {
  1286.     return((ClientData) NIL);
  1287.     }
  1288.     opFlags |= FSDM_LOG_START_ENTRY;
  1289.     clientData = domainPtr->domainOpsPtr->dirOpStart(domainPtr, opFlags, 
  1290.          name, nameLen, fileNumber, fileDescPtr,
  1291.          dirHandlePtr->hdr.fileID.minor, dirOffset, 
  1292.          dirHandlePtr->descPtr);
  1293. #ifdef lint
  1294.     clientData = Lfs_DirOpStart(domainPtr, opFlags, 
  1295.          name, nameLen, fileNumber, fileDescPtr,
  1296.          dirHandlePtr->hdr.fileID.minor, dirOffset, 
  1297.          dirHandlePtr->descPtr);
  1298.  
  1299.     clientData = Ofs_DirOpStart(domainPtr, opFlags, 
  1300.          name, nameLen, fileNumber, fileDescPtr,
  1301.          dirHandlePtr->hdr.fileID.minor, dirOffset, 
  1302.          dirHandlePtr->descPtr);
  1303. #endif /* lint */
  1304.  
  1305.     Fsdm_DomainRelease(dirHandlePtr->hdr.fileID.major);
  1306.     return(clientData);
  1307. }
  1308.  
  1309. /*
  1310.  *----------------------------------------------------------------------
  1311.  *
  1312.  * Fsdm_DirOpEnd --
  1313.  *
  1314.  *    Mark the end of a directory operation.
  1315.  *
  1316.  * Results:
  1317.  *    None
  1318.  *
  1319.  * Side effects:
  1320.  *    None.
  1321.  *
  1322.  *----------------------------------------------------------------------
  1323.  */
  1324.  
  1325. void
  1326. Fsdm_DirOpEnd(opFlags, dirHandlePtr, dirOffset, name, nameLen, fileNumber,
  1327.         type, fileDescPtr, clientData, status)
  1328.     int        opFlags;    /* Operation code and flags. See fsdm.h for
  1329.                  * definitions. */
  1330.     Fsio_FileIOHandle *dirHandlePtr;    /* Handle of directory being operated
  1331.                      * on. */
  1332.     int        dirOffset;    /* Byte offset into directory of the directory
  1333.                  * entry containing operation. -1 if offset
  1334.                  * is not known. */
  1335.     char    *name;        /* Name of object being operated on. */
  1336.     int        nameLen;    /* Length in characters of name. */
  1337.     int        fileNumber;    /* File number of objecting being operated on.*/
  1338.     int        type;        /* Type of the object being operated on. */
  1339.     Fsdm_FileDescriptor *fileDescPtr; /* FileDescriptor object being operated on
  1340.                        * before operation starts. */
  1341.     ClientData    clientData;    /* ClientData as returned by DirOpStart. */
  1342.     ReturnStatus status;    /* Return status of the operation, SUCCESS if
  1343.                  * operation succeeded. FAILURE otherwise. */
  1344. {
  1345.     register Fsdm_Domain        *domainPtr;
  1346.  
  1347.     domainPtr = Fsdm_DomainFetch(dirHandlePtr->hdr.fileID.major, FALSE);
  1348.     if (domainPtr == (Fsdm_Domain *)NIL) {
  1349.     return;
  1350.     }
  1351.     opFlags |= FSDM_LOG_END_ENTRY;
  1352.     domainPtr->domainOpsPtr->dirOpEnd(domainPtr, clientData, status, opFlags, 
  1353.          name, nameLen, fileNumber, fileDescPtr,
  1354.          dirHandlePtr->hdr.fileID.minor, dirOffset, 
  1355.          dirHandlePtr->descPtr);
  1356. #ifdef lint
  1357.     Lfs_DirOpEnd(domainPtr, clientData, status, opFlags, 
  1358.          name, nameLen, fileNumber, fileDescPtr,
  1359.          dirHandlePtr->hdr.fileID.minor, dirOffset, 
  1360.          dirHandlePtr->descPtr);
  1361.  
  1362.     Ofs_DirOpEnd(domainPtr, clientData, status, opFlags, 
  1363.          name, nameLen, fileNumber, fileDescPtr,
  1364.          dirHandlePtr->hdr.fileID.minor, dirOffset, 
  1365.          dirHandlePtr->descPtr);
  1366. #endif /* lint */
  1367.     Fsdm_DomainRelease(dirHandlePtr->hdr.fileID.major);
  1368.     return;
  1369. }
  1370.  
  1371.  
  1372.